#
# Cookbook Name:: wcs
# Library:: dependencycheck
#
# Copyright 2013, IBM Corp
#
# All rights reserved - Do Not Redistribute
#


module Orchestrate
  # Class to validate dependencies

  class Dependency

    # Initialize Zookeeper to verify if the URL supplied has the required value
     def initialize(url, statUrl, zkep)
        require 'thread'
        require 'rubygems'
        require 'json'
        require 'zk'
        @zk = ZK.new(zkep)
        @queue = Queue.new
        @path = url
        @statusUrl = statUrl
      end

    # Check if we can proceed - recipe has updated the url we are interested in
    def ready?(data)
      puts "ORCHESTRATE: Received event for " + @path + " #{data.inspect}"
      begin
        if data and not data.empty?
          instanceInfo = JSON.parse(data)
          if instanceInfo['ready']
            puts "ORCHESTRATE: Received go ahead !"
            return true
          end
        end
      rescue
        puts "ORCHESTRATE: Data not in JSON format (#{data})"
      end
      puts "ORCHESTRATE: We will wait for event at (" + @path + ") ..."
      return false    
    end

    # Validate that the URL specifed is in the right state to proceed or else block waiting for an event
    def validate!
      @subscription = @zk.register(@path) do |event|
        if event.node_changed? or event.node_created?
          data = @zk.get(@path, :watch => true).first
          if ready?(data)
            # Resumes ...
            @queue.push(:got_event)
          end
        end
      end

      data = nil
      if @zk.exists?(@path, :watch => true)
        data = @zk.get(@path, :watch => true).first
      end
      if not ready?(data)
        info = JSON.parse(@zk.get(@statusUrl).first)
        info.last[:blocked] = {:url => @path, :time => Time.now.to_i}
        @zk.create(@statusUrl, info.to_json, {:or => :set})

        @queue.pop
        # Continue
        info = JSON.parse(@zk.get(@statusUrl).first)
        info.last[:resume] = {:url => @path, :time => Time.now.to_i}
        @zk.create(@statusUrl, info.to_json, {:or => :set})
      end
    ensure
      @zk.close!
    end

    def publish!
       wsInfo = {:ready => true}
       @zk.create(@path, wsInfo.to_json, {:or => :set})

       # Track the publish
       info = JSON.parse(@zk.get(@statusUrl).first)
       info.last[:publish] = {:url => @path, :time => Time.now.to_i}
       @zk.create(@statusUrl, info.to_json, {:or => :set})
       puts "ORCHESTRATE: published " + @path
    ensure
      @zk.close!
    end
  end

end
    
    
    
    

